#ifndef __WS2812_STRIP_CONTROLLER_H__
#define __WS2812_STRIP_CONTROLLER_H__

#include "mcp_server.h"
#include "iot/thing.h"
#include <led_strip.h>
#include <driver/gpio.h>
#include <esp_log.h>
#include <vector>
#include <cmath>
#include <inttypes.h>
#include "board.h"  // 添加这个头文件以访问音频编解码器

#define WS2812_TAG "WS2812Controller"

class WS2812StripController : public iot::Thing {
private:
    led_strip_handle_t led_strip_;
    uint32_t num_leds_;
    gpio_num_t data_gpio_;
    bool power_ = false;
    uint8_t brightness_ = 30;    // 0-100
    uint8_t red_ = 255;          // 默认白色
    uint8_t green_ = 255;
    uint8_t blue_ = 255;
    
    // 动画相关
    bool animation_running_ = false;
    esp_timer_handle_t animation_timer_ = nullptr;
    int animation_step_ = 0;
    std::string current_effect_ = "solid";
    
    // 音乐律动相关
    std::vector<float> audio_levels_;    // 存储最近的音频电平
    int audio_history_size_ = 10;        // 音频历史缓冲区大小
    float bass_sensitivity_ = 1.5f;      // 低音敏感度
    int music_color_mode_ = 1;           // 音乐颜色模式: 0=彩虹, 1=单色脉冲, 2=频谱
    int audio_source_ = 1;               // 音频数据源: 0=麦克风输入, 1=播放输出

public:
    WS2812StripController(gpio_num_t data_gpio, uint32_t num_leds)
        : Thing("LEDStrip", "WS2812 LED Strip Controller"), num_leds_(num_leds), data_gpio_(data_gpio) {        
        InitializeLedStrip();
        RegisterMcpTools();
        
        // 初始化音频历史缓冲区
        audio_levels_.resize(audio_history_size_, 0.0f);
        
        ESP_LOGI(WS2812_TAG, "WS2812 Strip Controller initialized with %" PRIu32 " LEDs on GPIO %d", num_leds_, data_gpio_);
    }

    ~WS2812StripController() {
        if (animation_timer_) {
            esp_timer_stop(animation_timer_);
            esp_timer_delete(animation_timer_);
        }
        if (led_strip_) {
            led_strip_del(led_strip_);
        }
    }

private:
    void InitializeLedStrip() {
        // LED strip配置
        led_strip_config_t strip_config = {
            .strip_gpio_num = data_gpio_,
            .max_leds = num_leds_,
            .led_pixel_format = LED_PIXEL_FORMAT_GRB,  // WS2812使用GRB格式
            .led_model = LED_MODEL_WS2812,
            .flags = {
                .invert_out = false,
            }
        };

        // RMT配置
        led_strip_rmt_config_t rmt_config = {
            .clk_src = RMT_CLK_SRC_DEFAULT,
            .resolution_hz = 10 * 1000 * 1000, // 10MHz
            .flags = {
                .with_dma = false,
            }
        };

        // 创建LED strip
        ESP_ERROR_CHECK(led_strip_new_rmt_device(&strip_config, &rmt_config, &led_strip_));
        
        // 初始化为全黑
        led_strip_clear(led_strip_);
        
        // 创建动画定时器
        esp_timer_create_args_t timer_args = {
            .callback = [](void* arg) {
                static_cast<WS2812StripController*>(arg)->AnimationCallback();
            },
            .arg = this,
            .dispatch_method = ESP_TIMER_TASK,
            .name = "ws2812_animation"
        };
        ESP_ERROR_CHECK(esp_timer_create(&timer_args, &animation_timer_));
    }

    void UpdateAllLEDs() {
        if (!power_) {
            led_strip_clear(led_strip_);
            return;
        }

        uint8_t actual_r = (red_ * brightness_) / 100;
        uint8_t actual_g = (green_ * brightness_) / 100;
        uint8_t actual_b = (blue_ * brightness_) / 100;

        for (int i = 0; i < num_leds_; i++) {
            led_strip_set_pixel(led_strip_, i, actual_r, actual_g, actual_b);
        }
        led_strip_refresh(led_strip_);
    }

    void SetPixelColor(int index, uint8_t r, uint8_t g, uint8_t b) {
        if (index >= 0 && index < num_leds_) {
            uint8_t actual_r = (r * brightness_) / 100;
            uint8_t actual_g = (g * brightness_) / 100;
            uint8_t actual_b = (b * brightness_) / 100;
            led_strip_set_pixel(led_strip_, index, actual_r, actual_g, actual_b);
        }
    }

    void AnimationCallback() {
        if (!animation_running_ || !power_) return;

        if (current_effect_ == "rainbow") {
            RainbowEffect();
        } else if (current_effect_ == "breathing") {
            BreathingEffect();
        } else if (current_effect_ == "wave") {
            WaveEffect();
        } else if (current_effect_ == "scan") {
            ScanEffect();
        } else if (current_effect_ == "music") {
            MusicEffect();
        }
        
        led_strip_refresh(led_strip_);
        animation_step_++;
    }

    void RainbowEffect() {
        for (int i = 0; i < num_leds_; i++) {
            int hue = (animation_step_ * 2 + i * 360 / num_leds_) % 360;
            uint8_t r, g, b;
            HSVtoRGB(hue, 100, 100, r, g, b);
            SetPixelColor(i, r, g, b);
        }
    }

    void BreathingEffect() {
        float breath = (sin(animation_step_ * 0.1) + 1.0) / 2.0; // 0-1
        float actual_brightness = breath * brightness_ / 100.0f; // 转换为0.0-1.0范围
        
        for (int i = 0; i < num_leds_; i++) {
            uint8_t r = (uint8_t)(red_ * actual_brightness);
            uint8_t g = (uint8_t)(green_ * actual_brightness);
            uint8_t b = (uint8_t)(blue_ * actual_brightness);
            led_strip_set_pixel(led_strip_, i, r, g, b);
        }
    }

    void WaveEffect() {
        for (int i = 0; i < num_leds_; i++) {
            float wave = (sin((animation_step_ * 0.2) + (i * 0.5)) + 1.0) / 2.0;
            float intensity = wave * brightness_ / 100.0f; // 先计算强度系数
            uint8_t r = (uint8_t)(red_ * intensity);
            uint8_t g = (uint8_t)(green_ * intensity);
            uint8_t b = (uint8_t)(blue_ * intensity);
            led_strip_set_pixel(led_strip_, i, r, g, b);
        }
    }

    void ScanEffect() {
        led_strip_clear(led_strip_);
        int pos = animation_step_ % (num_leds_ * 2);
        if (pos >= num_leds_) {
            pos = num_leds_ * 2 - pos - 1;
        }
        
        // 设置主点
        SetPixelColor(pos, red_, green_, blue_);
        
        // 设置拖尾
        for (int i = 1; i <= 3 && pos - i >= 0; i++) {
            float fade = 1.0f / (i + 1); // 使用浮点数计算淡化系数
            SetPixelColor(pos - i, (uint8_t)(red_ * fade), (uint8_t)(green_ * fade), (uint8_t)(blue_ * fade));
        }
    }

    void MusicEffect() {
        // 获取当前音频电平
        float current_level = GetAudioLevel();
        
        // 添加调试日志
        static int debug_counter = 0;
        if (debug_counter++ % 100 == 0) { // 每100次调用打印一次
            ESP_LOGI("WS2812Music", "Music effect running, audio_source=%d, current_level=%.3f", audio_source_, current_level);
        }
        
        // 更新音频历史
        UpdateAudioHistory(current_level);
        
        // 计算平均电平和峰值
        float avg_level = GetAverageAudioLevel();
        float peak_level = GetPeakAudioLevel();
        
        // 根据音乐模式渲染效果
        switch (music_color_mode_) {
            case 0: // 彩虹模式 - 音量控制彩虹速度和亮度
                MusicRainbowMode(current_level, peak_level);
                break;
            case 1: // 单色脉冲 - 音量控制亮度脉冲
                MusicPulseMode(current_level, avg_level);
                break;
            case 2: // 频谱模式 - 模拟频谱分析器
                MusicSpectrumMode(current_level, peak_level);
                break;
            default:
                MusicRainbowMode(current_level, peak_level);
                break;
        }
    }

private:
    // 获取当前音频电平
    float GetAudioLevel() {
        auto& board = Board::GetInstance();
        auto* codec = board.GetAudioCodec();
        if (!codec) {
            return 0.0f;
        }
        
        std::vector<int16_t> audio_buffer(240); // 一帧音频数据
        bool has_data = false;
        
        if (audio_source_ == 0) {
            // 音频源0: 麦克风输入
            if (codec->input_enabled() && codec->InputData(audio_buffer)) {
                has_data = true;
            }
        } else if (audio_source_ == 1) {
            // 音频源1: 播放输出 (直接从codec获取最近的输出数据)
            if (codec->output_enabled() && codec->GetRecentOutputData(audio_buffer)) {
                has_data = true;
            } else {
                // 添加调试信息
                static int no_data_counter = 0;
                if (no_data_counter++ % 500 == 0) {
                    ESP_LOGW("WS2812Audio", "No playback audio data available. output_enabled=%d", codec->output_enabled());
                }
            }
        }
        
        if (has_data) {
            // 计算RMS音量
            float sum = 0.0f;
            for (int16_t sample : audio_buffer) {
                sum += (float)sample * sample;
            }
            float rms = sqrt(sum / audio_buffer.size());
            // 归一化到0-1范围，并应用敏感度
            return std::min(1.0f, (rms / 32768.0f) * bass_sensitivity_);
        }
        return 0.0f;
    }
    
    
    // 更新音频历史缓冲区
    void UpdateAudioHistory(float level) {
        // 移位数组，添加新值
        for (int i = audio_history_size_ - 1; i > 0; i--) {
            audio_levels_[i] = audio_levels_[i - 1];
        }
        audio_levels_[0] = level;
    }
    
    // 获取平均音频电平
    float GetAverageAudioLevel() {
        float sum = 0.0f;
        for (float level : audio_levels_) {
            sum += level;
        }
        return sum / audio_history_size_;
    }
    
    // 获取峰值音频电平
    float GetPeakAudioLevel() {
        float peak = 0.0f;
        for (float level : audio_levels_) {
            if (level > peak) peak = level;
        }
        return peak;
    }
    
    // 彩虹音乐模式
    void MusicRainbowMode(float current_level, float peak_level) {
        float intensity = current_level * 2.0f; // 增强效果
        for (int i = 0; i < num_leds_; i++) {
            // 基于音量和位置计算色相
            int hue = (animation_step_ * (int)(intensity * 10 + 1) + i * 360 / num_leds_) % 360;
            uint8_t r, g, b;
            HSVtoRGB(hue, 100, (int)(intensity * 100), r, g, b);
            SetPixelColor(i, r, g, b);
        }
    }
    
    // 单色脉冲模式
    void MusicPulseMode(float current_level, float avg_level) {
        // 基于当前音量创建脉冲效果
        float pulse_intensity = current_level * 1.5f;
        uint8_t pulse_brightness = (uint8_t)(pulse_intensity * brightness_);
        
        for (int i = 0; i < num_leds_; i++) {
            uint8_t r = (red_ * pulse_brightness) / 100;
            uint8_t g = (green_ * pulse_brightness) / 100;
            uint8_t b = (blue_ * pulse_brightness) / 100;
            led_strip_set_pixel(led_strip_, i, r, g, b);
        }
    }
    
    // 频谱模式 - 模拟频谱分析器
    void MusicSpectrumMode(float current_level, float peak_level) {
        // 将LED分成几个频段
        int bands = std::min(8, (int)num_leds_ / 4);
        int leds_per_band = num_leds_ / bands;
        
        for (int band = 0; band < bands; band++) {
            // 每个频段使用不同的音频历史数据模拟不同频率
            float band_level = audio_levels_[band % audio_history_size_] * (1.0f + band * 0.1f);
            int lit_leds = (int)(band_level * leds_per_band);
            
            for (int i = 0; i < leds_per_band; i++) {
                int led_index = band * leds_per_band + i;
                if (led_index >= num_leds_) break;
                
                if (i < lit_leds) {
                    // 从绿色(低)到红色(高)的渐变
                    uint8_t r = (uint8_t)((float)i / leds_per_band * 255);
                    uint8_t g = (uint8_t)(255 - (float)i / leds_per_band * 255);
                    uint8_t b = 0;
                    SetPixelColor(led_index, r, g, b);
                } else {
                    SetPixelColor(led_index, 0, 0, 0);
                }
            }
        }
    }

    void HSVtoRGB(int h, int s, int v, uint8_t& r, uint8_t& g, uint8_t& b) {
        float hf = h / 60.0;
        float sf = s / 100.0;
        float vf = v / 100.0;
        
        int i = (int)hf;
        float f = hf - i;
        float p = vf * (1 - sf);
        float q = vf * (1 - sf * f);
        float t = vf * (1 - sf * (1 - f));
        
        switch (i) {
            case 0: r = vf * 255; g = t * 255; b = p * 255; break;
            case 1: r = q * 255; g = vf * 255; b = p * 255; break;
            case 2: r = p * 255; g = vf * 255; b = t * 255; break;
            case 3: r = p * 255; g = q * 255; b = vf * 255; break;
            case 4: r = t * 255; g = p * 255; b = vf * 255; break;
            default: r = vf * 255; g = p * 255; b = q * 255; break;
        }
    }

    void StopAnimation() {
        if (animation_running_) {
            animation_running_ = false;
            esp_timer_stop(animation_timer_);
            current_effect_ = "solid";
        }
    }

    void StartAnimation(const std::string& effect, int interval_ms = 50) {
        StopAnimation();
        current_effect_ = effect;
        animation_step_ = 0;
        animation_running_ = true;
        esp_timer_start_periodic(animation_timer_, interval_ms * 1000);
    }

    void RegisterMcpTools() {
        auto& mcp_server = McpServer::GetInstance();
        
        // 获取灯带状态
        mcp_server.AddTool("self.ws2812.get_state", 
            "Get the current state of WS2812 LED strip", 
            PropertyList(), 
            [this](const PropertyList& properties) -> ReturnValue {
                char state[300];
                snprintf(state, sizeof(state), 
                    "{\"power\": %s, \"brightness\": %d, \"color\": {\"r\": %d, \"g\": %d, \"b\": %d}, \"num_leds\": %" PRIu32 ", \"effect\": \"%s\"}", 
                    power_ ? "true" : "false", brightness_, red_, green_, blue_, num_leds_, current_effect_.c_str());
                return std::string(state);
            });

        // 开关灯
        mcp_server.AddTool("self.ws2812.turn_on", 
            "Turn on WS2812 LED strip", 
            PropertyList(), 
            [this](const PropertyList& properties) -> ReturnValue {
                power_ = true;
                UpdateAllLEDs();
                ESP_LOGI(WS2812_TAG, "WS2812 strip turned on");
                return true;
            });

        mcp_server.AddTool("self.ws2812.turn_off", 
            "Turn off WS2812 LED strip", 
            PropertyList(), 
            [this](const PropertyList& properties) -> ReturnValue {
                power_ = false;
                StopAnimation();
                led_strip_clear(led_strip_);
                ESP_LOGI(WS2812_TAG, "WS2812 strip turned off");
                return true;
            });

        // 设置亮度
        mcp_server.AddTool("self.ws2812.set_brightness", 
            "Set brightness of WS2812 LED strip (0-100)", 
            PropertyList({Property("brightness", kPropertyTypeInteger, 50, 0, 100)}), 
            [this](const PropertyList& properties) -> ReturnValue {
                brightness_ = properties["brightness"].value<int>();
                if (current_effect_ == "solid") {
                    UpdateAllLEDs();
                }
                ESP_LOGI(WS2812_TAG, "WS2812 brightness set to %d", brightness_);
                return true;
            });

        // 设置颜色
        mcp_server.AddTool("self.ws2812.set_color", 
            "Set RGB color of WS2812 LED strip", 
            PropertyList({
                Property("red", kPropertyTypeInteger, 255, 0, 255),
                Property("green", kPropertyTypeInteger, 255, 0, 255),
                Property("blue", kPropertyTypeInteger, 255, 0, 255)
            }), 
            [this](const PropertyList& properties) -> ReturnValue {
                red_ = properties["red"].value<int>();
                green_ = properties["green"].value<int>();
                blue_ = properties["blue"].value<int>();
                
                StopAnimation();
                if (power_) {
                    UpdateAllLEDs();
                }
                ESP_LOGI(WS2812_TAG, "WS2812 color set to RGB(%d,%d,%d)", red_, green_, blue_);
                return true;
            });

        // 设置单个LED颜色
        mcp_server.AddTool("self.ws2812.set_pixel", 
            "Set color of a specific LED in the strip", 
            PropertyList({
                Property("index", kPropertyTypeInteger, 0, 0, num_leds_ - 1),
                Property("red", kPropertyTypeInteger, 255, 0, 255),
                Property("green", kPropertyTypeInteger, 255, 0, 255),
                Property("blue", kPropertyTypeInteger, 255, 0, 255)
            }), 
            [this](const PropertyList& properties) -> ReturnValue {
                if (!power_) return false;
                
                int index = properties["index"].value<int>();
                uint8_t r = properties["red"].value<int>();
                uint8_t g = properties["green"].value<int>();
                uint8_t b = properties["blue"].value<int>();
                
                StopAnimation();
                SetPixelColor(index, r, g, b);
                led_strip_refresh(led_strip_);
                
                ESP_LOGI(WS2812_TAG, "WS2812 pixel %d set to RGB(%d,%d,%d)", index, r, g, b);
                return true;
            });

        // 设置预设颜色模式
        mcp_server.AddTool("self.ws2812.set_preset", 
            "Set preset lighting mode", 
            PropertyList({Property("mode", kPropertyTypeString)}), 
            [this](const PropertyList& properties) -> ReturnValue {
                if (!power_) return false;
                
                std::string mode = properties["mode"].value<std::string>();
                StopAnimation();
                
                if (mode == "warm") {
                    red_ = 255; green_ = 180; blue_ = 100;
                } else if (mode == "cool") {
                    red_ = 100; green_ = 150; blue_ = 255;
                } else if (mode == "romantic") {
                    red_ = 255; green_ = 100; blue_ = 150;
                } else if (mode == "focus") {
                    red_ = 255; green_ = 255; blue_ = 255;
                } else if (mode == "relax") {
                    red_ = 150; green_ = 255; blue_ = 150;
                } else if (mode == "party") {
                    red_ = 255; green_ = 0; blue_ = 255;
                }
                
                UpdateAllLEDs();
                ESP_LOGI(WS2812_TAG, "WS2812 preset mode: %s", mode.c_str());
                return true;
            });

        // 设置动态效果
        mcp_server.AddTool("self.ws2812.set_effect", 
            "Set dynamic lighting effect", 
            PropertyList({
                Property("effect", kPropertyTypeString),
                Property("speed", kPropertyTypeInteger, 50, 10, 500)
            }), 
            [this](const PropertyList& properties) -> ReturnValue {
                if (!power_) return false;
                
                std::string effect = properties["effect"].value<std::string>();
                int speed = properties["speed"].value<int>();
                
                if (effect == "solid") {
                    StopAnimation();
                    UpdateAllLEDs();
                } else if (effect == "rainbow" || effect == "breathing" ||
                          effect == "wave" || effect == "scan" || effect == "music") {
                    StartAnimation(effect, speed);
                } else {
                    return false;
                }
                
                ESP_LOGI(WS2812_TAG, "WS2812 effect set to: %s (speed: %d)", effect.c_str(), speed);
                return true;
            });

        // 清空所有LED
        mcp_server.AddTool("self.ws2812.clear", 
            "Clear all LEDs (turn them off temporarily)", 
            PropertyList(), 
            [this](const PropertyList& properties) -> ReturnValue {
                StopAnimation();
                led_strip_clear(led_strip_);
                ESP_LOGI(WS2812_TAG, "WS2812 strip cleared");
                return true;
            });

        // 音乐律动模式设置
        mcp_server.AddTool("self.ws2812.set_music_mode", 
            "Set music reactive mode (0=rainbow, 1=pulse, 2=spectrum)", 
            PropertyList({
                Property("mode", kPropertyTypeInteger, 0, 0, 2),
                Property("sensitivity", kPropertyTypeInteger, 15, 5, 30)  // 使用整数，范围5-30，对应0.5-3.0
            }), 
            [this](const PropertyList& properties) -> ReturnValue {
                if (!power_) return false;
                
                music_color_mode_ = properties["mode"].value<int>();
                bass_sensitivity_ = properties["sensitivity"].value<int>() / 10.0f;  // 转换为float
                
                // 自动启动音乐效果
                StartAnimation("music", 50);
                
                ESP_LOGI(WS2812_TAG, "Music mode set to %d, sensitivity %.1f, music effect started", 
                    music_color_mode_, bass_sensitivity_);
                return true;
            });

        // 音频数据源设置
        mcp_server.AddTool("self.ws2812.set_audio_source", 
            "Set audio data source for music effects (0=microphone, 1=playback)", 
            PropertyList({Property("source", kPropertyTypeInteger, 0, 0, 1)}), 
            [this](const PropertyList& properties) -> ReturnValue {
                audio_source_ = properties["source"].value<int>();
                ESP_LOGI(WS2812_TAG, "Audio source set to %d (%s)", audio_source_, 
                    audio_source_ == 0 ? "microphone" : "playback");
                return true;
            });
    }
};

#endif // __WS2812_STRIP_CONTROLLER_H__
